package com.zenithmind.chat.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.chat.mapper.ChatFriendMapper;
import com.zenithmind.chat.mapper.ChatPrivateMessageMapper;
import com.zenithmind.chat.mapper.ChatPrivateSessionMapper;
import com.zenithmind.chat.pojo.entity.ChatFriend;
import com.zenithmind.chat.pojo.dto.ChatPrivateMessageDTO;
import com.zenithmind.chat.pojo.entity.ChatPrivateMessage;
import com.zenithmind.chat.pojo.entity.ChatPrivateSession;
import com.zenithmind.chat.pojo.vo.ChatPrivateMessageVO;
import com.zenithmind.chat.service.ChatPrivateMessageService;
import com.zenithmind.common.context.UserContext;
import com.zenithmind.common.exception.BusinessException;
import com.zenithmind.common.result.PageResult;
import com.zenithmind.common.utils.BeanCopyUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 私聊消息服务实现类
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ChatPrivateMessageServiceImpl extends ServiceImpl<ChatPrivateMessageMapper, ChatPrivateMessage> 
        implements ChatPrivateMessageService {

    private final ChatPrivateSessionMapper sessionMapper;
    private final ChatFriendMapper friendMapper;

    @Override
    public PageResult<ChatPrivateMessageVO> getMessagePage(String sessionId, String userId,
                                                          Integer pageNum, Integer pageSize) {
        Page<ChatPrivateMessage> page = new Page<>(pageNum, pageSize);

        LambdaQueryWrapper<ChatPrivateMessage> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ChatPrivateMessage::getSessionId, sessionId)
               .orderByDesc(ChatPrivateMessage::getSendTime);

        IPage<ChatPrivateMessage> result = page(page, wrapper);

        List<ChatPrivateMessageVO> voList = result.getRecords().stream()
            .map(message -> convertToVO(message, userId))
            .collect(Collectors.toList());

        return PageResult.of(voList, result.getTotal());
    }

    @Override
    public List<ChatPrivateMessageVO> getSessionMessages(String sessionId, String userId,
                                                        String lastMessageId, Integer limit) {
        LambdaQueryWrapper<ChatPrivateMessage> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ChatPrivateMessage::getSessionId, sessionId)
               .eq(ChatPrivateMessage::getStatus, 1); // 正常状态

        if (StringUtils.hasText(lastMessageId)) {
            wrapper.lt(ChatPrivateMessage::getId, lastMessageId);
        }

        wrapper.orderByDesc(ChatPrivateMessage::getSendTime);

        if (limit != null && limit > 0) {
            wrapper.last("LIMIT " + limit);
        }

        List<ChatPrivateMessage> messages = list(wrapper);
        return messages.stream()
            .map(message -> convertToVO(message, userId))
            .collect(Collectors.toList());
    }

    @Override
    public ChatPrivateMessageVO getMessageById(String id, String userId) {
        ChatPrivateMessage message = getById(id);
        if (message == null) {
            throw new BusinessException("消息不存在");
        }

        ChatPrivateMessageVO messageVO = BeanCopyUtils.copyBean(message, ChatPrivateMessageVO.class);
        
        // 设置消息类型文本
        messageVO.setMessageTypeText(getMessageTypeText(message.getMessageType()));
        messageVO.setStatusText(getMessageStatusText(message.getStatus()));
        
        // 检查是否为当前用户发送
        messageVO.setIsSelf(Objects.equals(message.getSenderId(), userId));
        
        // 检查是否可以撤回（发送后2分钟内且为自己发送的消息）
        boolean canRecall = messageVO.getIsSelf() && 
                           message.getStatus() == 1 && 
                           message.getSendTime().isAfter(LocalDateTime.now().minusMinutes(2));
        messageVO.setCanRecall(canRecall);
        
        return messageVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String sendPrivateMessage(ChatPrivateMessageDTO messageDTO, String userId) {
        // 验证参数
        validateMessageDTO(messageDTO);
        
        // 检查发送权限
        if (!checkSendPermission(userId, messageDTO.getReceiverId())) {
            throw new BusinessException("无权限发送消息");
        }
        
        // 创建或获取会话
        String sessionId = createOrGetSession(userId, messageDTO.getReceiverId());
        
        // 创建消息
        ChatPrivateMessage message = BeanCopyUtils.copyBean(messageDTO, ChatPrivateMessage.class);
        message.setSessionId(sessionId);
        message.setSenderId(userId);
        message.setSenderName(UserContext.getUsername());
        message.setSenderAvatar(""); // TODO: 从用户服务获取头像
        message.setStatus(1); // 正常状态
        message.setIsRead(0); // 未读
        message.setSendTime(LocalDateTime.now());
        
        // 处理回复消息
        if (StringUtils.hasText(messageDTO.getReplyToId())) {
            ChatPrivateMessage replyToMessage = getById(messageDTO.getReplyToId());
            if (replyToMessage != null) {
                message.setReplyToContent(replyToMessage.getContent());
            }
        }
        
        save(message);
        
        // 更新会话信息
        updateSessionLastMessage(sessionId, message);
        
        log.info("用户 {} 发送私聊消息到 {}: {}", userId, messageDTO.getReceiverId(), message.getId());
        return message.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean recallMessage(String id, String userId, String reason) {
        ChatPrivateMessage message = getById(id);
        if (message == null) {
            throw new BusinessException("消息不存在");
        }
        
        // 检查权限（只能撤回自己的消息）
        if (!Objects.equals(message.getSenderId(), userId)) {
            throw new BusinessException("无权限撤回该消息");
        }
        
        // 检查时间限制（发送后2分钟内可撤回）
        if (message.getSendTime().isBefore(LocalDateTime.now().minusMinutes(2))) {
            throw new BusinessException("消息发送超过2分钟，无法撤回");
        }
        
        // 更新消息状态
        message.setStatus(2); // 已撤回
        message.setRecallTime(LocalDateTime.now());
        message.setRecallReason(reason);
        updateById(message);
        
        log.info("用户 {} 撤回私聊消息: {}", userId, id);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteMessage(String id, String userId) {
        ChatPrivateMessage message = getById(id);
        if (message == null) {
            throw new BusinessException("消息不存在");
        }
        
        // 检查权限（只能删除自己的消息）
        if (!Objects.equals(message.getSenderId(), userId)) {
            throw new BusinessException("无权限删除该消息");
        }
        
        // 软删除
        removeById(id);
        
        log.info("用户 {} 删除私聊消息: {}", userId, id);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteMessagesBatch(List<String> ids, String userId) {
        if (CollectionUtils.isEmpty(ids)) {
            return false;
        }
        
        for (String id : ids) {
            deleteMessage(id, userId);
        }
        
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean markMessagesAsRead(String sessionId, String userId) {
        LocalDateTime readTime = LocalDateTime.now();

        // 使用MyBatis-Plus的update方法
        LambdaQueryWrapper<ChatPrivateMessage> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ChatPrivateMessage::getSessionId, sessionId)
               .eq(ChatPrivateMessage::getReceiverId, userId)
               .eq(ChatPrivateMessage::getIsRead, 0)
               .eq(ChatPrivateMessage::getStatus, 1);

        ChatPrivateMessage updateMessage = new ChatPrivateMessage();
        updateMessage.setIsRead(1);
        updateMessage.setReadTime(readTime);

        boolean result = update(updateMessage, wrapper);

        // 更新会话未读数
        updateSessionUnreadCount(sessionId, userId);

        log.info("用户 {} 标记会话 {} 消息为已读", userId, sessionId);
        return result;
    }

    @Override
    public List<ChatPrivateMessageVO> searchMessages(String sessionId, String keyword, Integer messageType,
                                                    String startTime, String endTime, Integer limit) {
        LocalDateTime start = StringUtils.hasText(startTime) ? LocalDateTime.parse(startTime) : null;
        LocalDateTime end = StringUtils.hasText(endTime) ? LocalDateTime.parse(endTime) : null;

        LambdaQueryWrapper<ChatPrivateMessage> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ChatPrivateMessage::getSessionId, sessionId)
               .eq(ChatPrivateMessage::getStatus, 1)
               .like(StringUtils.hasText(keyword), ChatPrivateMessage::getContent, keyword)
               .eq(messageType != null, ChatPrivateMessage::getMessageType, messageType)
               .ge(start != null, ChatPrivateMessage::getSendTime, start)
               .le(end != null, ChatPrivateMessage::getSendTime, end)
               .orderByDesc(ChatPrivateMessage::getSendTime);

        if (limit != null && limit > 0) {
            wrapper.last("LIMIT " + limit);
        }

        List<ChatPrivateMessage> messages = list(wrapper);
        return messages.stream()
            .map(message -> convertToVO(message, null))
            .collect(Collectors.toList());
    }

    @Override
    public Integer getUnreadMessageCount(String sessionId, String userId) {
        // 使用MyBatis-Plus的count方法
        LambdaQueryWrapper<ChatPrivateMessage> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ChatPrivateMessage::getSessionId, sessionId)
               .eq(ChatPrivateMessage::getReceiverId, userId)
               .eq(ChatPrivateMessage::getIsRead, 0)
               .eq(ChatPrivateMessage::getStatus, 1);

        return Math.toIntExact(count(wrapper));
    }

    @Override
    public ChatPrivateMessageVO getLatestMessage(String sessionId, String userId) {
        LambdaQueryWrapper<ChatPrivateMessage> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ChatPrivateMessage::getSessionId, sessionId)
               .eq(ChatPrivateMessage::getStatus, 1)
               .orderByDesc(ChatPrivateMessage::getSendTime)
               .last("LIMIT 1");

        ChatPrivateMessage message = getOne(wrapper);
        return message != null ? convertToVO(message, userId) : null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createOrGetSession(String userId, String friendId) {
        // 确保用户ID顺序一致（小的在前）
        String user1Id = userId.compareTo(friendId) < 0 ? userId : friendId;
        String user2Id = userId.compareTo(friendId) < 0 ? friendId : userId;
        
        // 查找现有会话
        LambdaQueryWrapper<ChatPrivateSession> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ChatPrivateSession::getUser1Id, user1Id)
               .eq(ChatPrivateSession::getUser2Id, user2Id);
        
        ChatPrivateSession session = sessionMapper.selectOne(wrapper);
        
        if (session == null) {
            // 创建新会话
            session = new ChatPrivateSession();
            session.setUser1Id(user1Id);
            session.setUser2Id(user2Id);
            // TODO: 获取用户名称
            session.setUser1Name("User1");
            session.setUser2Name("User2");
            session.setUser1UnreadCount(0);
            session.setUser2UnreadCount(0);
            session.setStatus(1);
            
            sessionMapper.insert(session);
            log.info("创建新的私聊会话: {} - {}", user1Id, user2Id);
        }
        
        return session.getId();
    }

    @Override
    public List<Object> getUserSessions(String userId) {
        // TODO: 实现获取用户会话列表
        return List.of();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteSession(String sessionId, String userId) {
        ChatPrivateSession session = sessionMapper.selectById(sessionId);
        if (session == null) {
            throw new BusinessException("会话不存在");
        }
        
        // 检查权限
        if (!Objects.equals(session.getUser1Id(), userId) && !Objects.equals(session.getUser2Id(), userId)) {
            throw new BusinessException("无权限删除该会话");
        }
        
        // 设置删除时间
        LocalDateTime now = LocalDateTime.now();
        if (Objects.equals(session.getUser1Id(), userId)) {
            session.setUser1DeleteTime(now);
        } else {
            session.setUser2DeleteTime(now);
        }
        
        sessionMapper.updateById(session);
        
        log.info("用户 {} 删除会话 {}", userId, sessionId);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean clearSessionMessages(String sessionId, String userId) {
        // TODO: 实现清空会话消息
        return true;
    }

    @Override
    public Object getMessageStatistics(String userId, String startTime, String endTime) {
        // 使用MyBatis-Plus的查询方法来统计
        LambdaQueryWrapper<ChatPrivateMessage> wrapper = new LambdaQueryWrapper<>();

        if (StringUtils.hasText(userId)) {
            wrapper.and(w -> w.eq(ChatPrivateMessage::getSenderId, userId)
                             .or()
                             .eq(ChatPrivateMessage::getReceiverId, userId));
        }

        if (StringUtils.hasText(startTime)) {
            wrapper.ge(ChatPrivateMessage::getSendTime, LocalDateTime.parse(startTime));
        }

        if (StringUtils.hasText(endTime)) {
            wrapper.le(ChatPrivateMessage::getSendTime, LocalDateTime.parse(endTime));
        }

        // 简化统计，实际项目中可以使用更复杂的统计方法
        long totalMessages = count(wrapper);

        // 创建统计对象（简化版）
        return new Object() {
            public final Long total = totalMessages;
            public final Long text = 0L;
            public final Long image = 0L;
            public final Long file = 0L;
            public final Long voice = 0L;
            public final Long video = 0L;
        };
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer cleanExpiredMessages(Integer days) {
        LocalDateTime expireTime = LocalDateTime.now().minusDays(days);

        // 使用MyBatis-Plus的update方法进行软删除
        LambdaQueryWrapper<ChatPrivateMessage> wrapper = new LambdaQueryWrapper<>();
        wrapper.lt(ChatPrivateMessage::getSendTime, expireTime)
               .eq(ChatPrivateMessage::getIsDeleted, 0);

        ChatPrivateMessage updateMessage = new ChatPrivateMessage();
        updateMessage.setIsDeleted(1);
        updateMessage.setUpdateTime(LocalDateTime.now());

        boolean result = update(updateMessage, wrapper);

        // 返回影响的行数（这里简化处理，实际可以通过其他方式获取）
        return result ? 1 : 0;
    }

    @Override
    public Boolean checkSendPermission(String userId, String receiverId) {
        // 检查是否为好友关系
        LambdaQueryWrapper<ChatFriend> friendWrapper = new LambdaQueryWrapper<>();
        friendWrapper.eq(ChatFriend::getUserId, userId)
                    .eq(ChatFriend::getFriendId, receiverId)
                    .eq(ChatFriend::getStatus, 1)
                    .eq(ChatFriend::getIsDeleted, 0);

        long friendCount = friendMapper.selectCount(friendWrapper);
        if (friendCount == 0) {
            return false;
        }

        // 检查是否被拉黑
        LambdaQueryWrapper<ChatFriend> blockWrapper = new LambdaQueryWrapper<>();
        blockWrapper.eq(ChatFriend::getUserId, receiverId)
                   .eq(ChatFriend::getFriendId, userId)
                   .eq(ChatFriend::getStatus, 2)
                   .eq(ChatFriend::getIsDeleted, 0);

        long blockCount = friendMapper.selectCount(blockWrapper);
        return blockCount == 0;
    }

    // 私有方法
    private void validateMessageDTO(ChatPrivateMessageDTO messageDTO) {
        if (!StringUtils.hasText(messageDTO.getReceiverId())) {
            throw new BusinessException("接收者ID不能为空");
        }
        
        if (messageDTO.getMessageType() == null || messageDTO.getMessageType() < 1 || messageDTO.getMessageType() > 8) {
            throw new BusinessException("消息类型无效");
        }
        
        if (messageDTO.getMessageType() == 1 && !StringUtils.hasText(messageDTO.getContent())) {
            throw new BusinessException("文本消息内容不能为空");
        }
    }

    private String getMessageTypeText(Integer type) {
        switch (type) {
            case 1: return "文本消息";
            case 2: return "图片消息";
            case 3: return "文件消息";
            case 4: return "语音消息";
            case 5: return "视频消息";
            case 6: return "系统消息";
            case 7: return "表情消息";
            case 8: return "链接消息";
            default: return "未知消息";
        }
    }

    private String getMessageStatusText(Integer status) {
        switch (status) {
            case 1: return "正常";
            case 2: return "已撤回";
            case 3: return "已删除";
            default: return "未知";
        }
    }

    private void updateSessionLastMessage(String sessionId, ChatPrivateMessage message) {
        ChatPrivateSession session = sessionMapper.selectById(sessionId);
        if (session != null) {
            session.setLastMessageId(message.getId());
            session.setLastMessageTime(message.getSendTime());
            session.setLastMessageContent(formatMessageContent(message));
            
            // 更新接收者未读数
            if (Objects.equals(session.getUser1Id(), message.getReceiverId())) {
                session.setUser1UnreadCount(session.getUser1UnreadCount() + 1);
            } else {
                session.setUser2UnreadCount(session.getUser2UnreadCount() + 1);
            }
            
            sessionMapper.updateById(session);
        }
    }

    private void updateSessionUnreadCount(String sessionId, String userId) {
        ChatPrivateSession session = sessionMapper.selectById(sessionId);
        if (session != null) {
            if (Objects.equals(session.getUser1Id(), userId)) {
                session.setUser1UnreadCount(0);
            } else {
                session.setUser2UnreadCount(0);
            }
            sessionMapper.updateById(session);
        }
    }

    private String formatMessageContent(ChatPrivateMessage message) {
        switch (message.getMessageType()) {
            case 1: return message.getContent();
            case 2: return "[图片]";
            case 3: return "[文件]";
            case 4: return "[语音]";
            case 5: return "[视频]";
            case 6: return message.getContent();
            case 7: return "[表情]";
            case 8: return "[链接]";
            default: return "[未知消息]";
        }
    }

    /**
     * 转换为VO对象
     */
    private ChatPrivateMessageVO convertToVO(ChatPrivateMessage message, String userId) {
        ChatPrivateMessageVO vo = BeanCopyUtils.copyBean(message, ChatPrivateMessageVO.class);

        // 设置消息类型文本
        vo.setMessageTypeText(getMessageTypeText(message.getMessageType()));
        vo.setStatusText(getMessageStatusText(message.getStatus()));

        // 检查是否为当前用户发送
        vo.setIsSelf(Objects.equals(message.getSenderId(), userId));

        // 检查是否可以撤回（发送后2分钟内且为自己发送的消息）
        boolean canRecall = vo.getIsSelf() &&
                           message.getStatus() == 1 &&
                           message.getSendTime().isAfter(LocalDateTime.now().minusMinutes(2));
        vo.setCanRecall(canRecall);

        return vo;
    }
}
